home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
PowerPlant
/
TCodeModule & Friends
/
TCodeModule.cp
< prev
next >
Wrap
Text File
|
1996-05-04
|
3KB
|
154 lines
/*
File: TCodeModule.cp
Contains: CFM-based code resource class
Copyright: ©1995-1996 Chris K. Thomas. All Rights Reserved.
Version: 1.0
*/
// %%% no mixed-mode stuff herein- must be using same runtime
// as the code module
// %%% - doesn't currently support more than one code fragment
// in the data fork
#include "TCodeModule.h"
#include <UException.h> //PP exceptions
// —————• Liftime———————————————————————————————————————————————————————————————
TCodeModule::TCodeModule(FSSpec &inSpec)
{
mGood = false;
mSpec = inSpec;
mResource = NULL;
mResFileRef = -1;
}
TCodeModule::~TCodeModule()
{
Disconnect();
}
// —————• Connections—————————————————————————————————————————————————————————————
// * always connect before getting a method
void
TCodeModule::Connect()
{
#if GENERATINGCFM
OSErr theErr;
Str255 errStr;
Ptr main;
theErr = GetDiskFragment(&mSpec, 0, kCFragGoesToEOF, "\pEditor", kNewCFragCopy,
&mConnector, &main, errStr);
ThrowIfOSErr_(theErr);
mGood = true;
#else
DebugStr("\pTCodeModule::Connect() Unimplemented on 68k");
#endif
}
void
TCodeModule::Connect(ResType inType, long inID)
{
mResFileRef = FSpOpenResFile(&mSpec, fsRdPerm);
ThrowIfResError_();
mResource = GetResource(inType, inID);
if(mResource == NULL)
{
FSClose(mResFileRef);
throw 'nilp';
}
HLockHi(mResource);
#if GENERATINGCFM
Ptr main;
Str255 errStr;
OSErr theErr;
theErr = GetMemFragment(*mResource, GetHandleSize(mResource), mSpec.name,
kNewCFragCopy, &mConnector, &main, errStr);
if(theErr != noErr)
{
ReleaseResource(mResource);
mResource = NULL;
throw theErr;
}
#endif
}
// * Disconnect is called in the destructor, but doesn't hurt
// * to Disconnect manually.
void
TCodeModule::Disconnect()
{
#if GENERATINGCFM
if(mGood)
CloseConnection(&mConnector);
#endif
if(mResource)
ReleaseResource(mResource);
if(mResFileRef != -1)
FSClose(mResFileRef);
mGood = false;
mResource = NULL;
mResFileRef = -1;
}
// —————• Access——————————————————————————————————————————————————————————————————
ProcPtr
TCodeModule::GetMethod(const unsigned char *inMethodName)
// • get the vector address of inMethodName under CFM
// • just return the main entrypoint if old 68k runtime
{
#if (!GENERATINGCFM)
#pragma unused (inMethodName)
#endif
ProcPtr outAddress = NULL;
#if GENERATINGCFM
ThrowIfNot_(mGood);
OSErr theErr;
CFragSymbolClass fragClass;
theErr = FindSymbol(mConnector, inMethodName, (Ptr*)&outAddress, &fragClass);
// * it’s easier for a calling proc to check for null
// than to handle exceptions
if(theErr == fragSymbolNotFound)
{
return NULL;
}
else if(theErr != noErr)
{
ThrowIfOSErr_(theErr);
}
if(fragClass != kTVectorCFragSymbol) // if it's not a transition vector
{
throw fragInvalidFragmentUsage;
}
#else
ThrowIfNULL_(outAddress);
outAddress = *(ProcPtr*)mResource;
#endif
return outAddress;
}